////////////////////////////////////////////////////////////////////////////////////////////////////
/// Copyright (c) 2009 - 2010 RacoonStudios
///
/// Permission is hereby granted, free of charge, to any person obtaining a copy of this
/// software and associated documentation files (the "Software"), to deal in the Software
/// without restriction, including without limitation the rights to use, copy, modify, merge,
/// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
/// to whom the Software is furnished to do so, subject to the following conditions:
///
/// The above copyright notice and this permission notice shall be included in all copies or
/// substantial portions of the Software.
///
/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
/// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
/// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
/// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
/// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
/// DEALINGS IN THE SOFTWARE.
////////////////////////////////////////////////////////////////////////////////////////////////////

#pragma once
#ifndef win32thread_h__
#define win32thread_h__

#include "core/referencecount.h"
#include "threading/event.h"
#include "threading/threadid.h"
#include "system/cpu.h"

namespace Win32
{
	////////////////////////////////////////////////////////////////////////////////////////////////////
	/// \class	Win32Thread
	///
	/// \brief	Window 32 thread. 
	/// 
	/// \todo 	Add documentation!
	///
	/// \author	Markus
	/// \date	21.02.2010
	////////////////////////////////////////////////////////////////////////////////////////////////////
	class Win32Thread : public Core::ReferenceCount
	{
		RE_DeclareClass(Win32::Win32Thread);

	public:

		enum Priority
		{
			VeryLow,
			Low, 
			Normal,
			High,
			VeryHigh
		};



		Win32Thread();

		virtual ~Win32Thread();



		void SetPriority(Priority pri);

		void SetCoreID(System::CPU::CoreID id);

		void SetStackSize(tSize size);

		void SetName(const Helper::String & name);

		Priority GetPriority() const;

		System::CPU::CoreID GetCoreID() const;

		tSize GetStackSize() const;

		const Helper::String & GetName() const;



		void Start();

		void Stop();

		bool IsRunning() const;



		static void YieldThread();

		static void SetMyThreadName(const char * name);

		static const char * GetMyThreadName();

		static Threading::ThreadID GetMyThreadID();

	protected:

		virtual void EmitWakeupSignal();

		virtual void DoWork();

		bool ThreadStopRequested() const;

	private:

		static DWORD WINAPI ThreadProc(LPVOID self);



		HANDLE m_threadHandle;

		Threading::Event m_startEvent;
		Threading::Event m_stopEvent;
		Priority m_priority;

		tSize m_stackSize;

		Helper::String m_name;

		System::CPU::CoreID m_coreID;

		ThreadLocal static const char * ThreadName;

	};

}

#endif // win32thread_h__